package p3.ejemplos;

import java.io.*;
import java.net.*;

import p3.IServidor;


/**
 * Servidor Iterativo. No comienza a servir una petición hasta que no 
 * ha terminado con la anterior.
 * @author JAPF
 *
 */
public class ServidorIterativo implements IServidor {
	
	
	protected int listenPort = 3000;
	ServerSocket server;
	
	/**
	 * Crea el socket servidor y se pone a la espera de peticiones de servicio.
	 * Cuando llega una petición de servicio crea un hilo para que la sirva
	 * y se pone inmediatamente a la espera de la siguiente.
	 */
	public void aceptarConexiones() throws BindException, IOException {
		System.out.println("Servidor Iterativo. Aceptar. 1");
		try{
			server = new ServerSocket();
			server.setReuseAddress(true);
			server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), listenPort), 5);
			System.out.println("Servidor Iterativo. Aceptar. 2");

			Socket incomingConnection = null;
			while (true) {
				incomingConnection = server.accept();
				handleConnection(incomingConnection);
			}
		}
		catch(BindException be){
			be.printStackTrace();	
			throw be;
		}
		catch(IOException ioe){
			ioe.printStackTrace();		
			throw ioe;
		}
		
	}
	
	/**
	 * Interacciona con el socket cliente para enviarle los contenidos
	 * del fichero solicitado. Es un método no bloqueante. 
	 * Retorna en cuanto empieza el servicio. 
	 * @param incomingConection
	 */
	public void handleConnection(Socket socketToHandle){
		System.out.println("Servidor Iterativo. Handling.");
		new FileRequestHandler(socketToHandle).doService();
	}
	
	public void shutdown(){
		try {
			if (server != null) server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void finalize(){
		shutdown();
	}
	

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
       ServidorIterativo servidor = new ServidorIterativo();
       servidor.aceptarConexiones();
	}

}
